package com.xms.security.service.dataauth;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xms.security.data.RoleobjectaccessMapper;
import com.xms.security.entity.RoleObjectAccess;
import com.xms.security.identity.ICurrentUser;
import com.xms.utils.CollectionUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author migo
 * @since 2021-09-04
 */
@Service
public class RoleObjectAccessService extends ServiceImpl<RoleobjectaccessMapper, RoleObjectAccess> implements IRoleObjectAccessService {

    @Override
    public List<UUID> authorized(ICurrentUser currentUser, int objectTypeCode, List<UUID> objectId) {
        if (CollectionUtil.isEmpty(objectId) || currentUser.getRoles() == null) {
            return null;
        }
        List<UUID> result = new ArrayList<>();
        List<UUID> userInRole = currentUser.getRoles();
        if (CollectionUtil.notEmpty(userInRole)) {
            List<RoleObjectAccess> roaList = super.list(new LambdaQueryWrapper<RoleObjectAccess>()
                    .in(RoleObjectAccess::getObjectid, objectId)
                    .in(RoleObjectAccess::getRoleid, userInRole)
                    .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
            result.addAll(objectId);
            result.removeIf(x -> !roaList.stream().anyMatch(r -> r.getObjectid() == x));
            return result;
        }
        return result;
    }

    @Override
    public boolean createMany(int objectTypeCode, UUID objectId, List<UUID> roleId) {
        if (CollectionUtil.isEmpty(roleId)) {
            return false;
        }
        List<RoleObjectAccess> accessList = new ArrayList<>();
        for (UUID rid : roleId) {
            RoleObjectAccess ar = new RoleObjectAccess();
            ar.setObjectid(objectId);
            ar.setObjecttypecode(objectTypeCode);
            ar.setRoleid(rid);
            accessList.add(ar);
        }
        return super.saveBatch(accessList);
    }

    @Override
    public boolean deleteByObjectId(UUID objectId, int objectTypeCode) {
        return super.remove(new LambdaQueryWrapper<RoleObjectAccess>()
                .eq(RoleObjectAccess::getObjectid, objectId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
    }

    @Override
    public boolean deleteByObjectId(int objectTypeCode, List<UUID> objectId) {
        return super.remove(new LambdaQueryWrapper<RoleObjectAccess>()
                .in(RoleObjectAccess::getObjectid, objectId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
    }

    @Override
    public boolean exists(UUID objectId, int objectTypeCode, List<UUID> roleId) {
        return super.count(new LambdaQueryWrapper<RoleObjectAccess>()
                .eq(RoleObjectAccess::getObjectid, objectId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode)
                .in(RoleObjectAccess::getRoleid, roleId)) > 0;
    }

    @Override
    public boolean deleteByRole(UUID roleId, int objectTypeCode) {
        return super.remove(new LambdaQueryWrapper<RoleObjectAccess>()
                .eq(RoleObjectAccess::getRoleid, roleId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
    }

    @Override
    public List<RoleObjectAccess> getRolePermissions(UUID roleId, int objectTypeCode) {
        return super.list(new LambdaQueryWrapper<RoleObjectAccess>()
                .eq(RoleObjectAccess::getRoleid, roleId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
    }

    @Override
    public List<RoleObjectAccess> getRolePermissions(int objectTypeCode, List<UUID> roleId) {
        return super.list(new LambdaQueryWrapper<RoleObjectAccess>()
                .in(RoleObjectAccess::getRoleid, roleId)
                .eq(RoleObjectAccess::getObjecttypecode, objectTypeCode));
    }
}
